package com.bsj.power.common.http;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bsj.power.common.config.global.JsonResultEnum;
import com.bsj.power.common.constant.ApiConstants;
import com.bsj.power.common.constant.NumericalConstants;
import com.bsj.power.common.def.entity.job.Job;
import com.bsj.power.common.def.entity.job.QualityPlan;
import com.bsj.power.common.def.entity.locationDevice.LocationDevice;
import com.bsj.power.common.def.entity.personnel.Personnel;
import com.bsj.power.common.def.http.dto.WorkHttpDTO;
import com.bsj.power.common.def.http.vo.WorkHttpVO;
import com.bsj.power.common.def.vo.pls.httpVo.HttpPersonnelVO;
import com.bsj.power.common.def.vo.pls.httpVo.HttpQualityPlanVO;
import com.bsj.power.common.def.vo.pls.httpVo.HttpTagInfoVO;
import com.bsj.power.common.util.DateUtils;
import com.bsj.power.common.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.cms.PasswordRecipientInfo;
import org.springframework.util.CollectionUtils;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yinhao
 * @version 1.0
 * @description 同步数据HTTP类
 * @date 2024/7/10
 */
@Slf4j
public class ExternalAccessHttp {

    /**
     * 机组号转换map
     */
    private static Map<String, Integer> unitNumMap;

    static {
        unitNumMap = new HashMap<>();
        unitNumMap.put("HY1", 1);
        unitNumMap.put("HY2", 2);
        unitNumMap.put("HY3", 3);
        unitNumMap.put("HY4", 4);
        unitNumMap.put("HY5", 5);
        unitNumMap.put("HY6", 6);
        unitNumMap.put("HY7", 7);
        unitNumMap.put("HY8", 8);
        unitNumMap.put("HY9", 9);
        unitNumMap.put("HY10", 10);
        unitNumMap.put("HYG", 100);
        unitNumMap.put("HYS", 101);
        unitNumMap.put("HYL", 102);
        unitNumMap.put("HYP", 103);
        unitNumMap.put("HYZ", 104);
        unitNumMap.put("NA", 105);
    }

    /**
     * 工单数据HTTP请求
     * 只返回INPRG ASSIGN1 PREPARE1三种状态
     *
     * @param address 请求地址
     * @param dto     请求接口参数
     * @return
     */
    public static List<Job> workInfoHttpGet(String address, WorkHttpDTO dto) {
        List<Job> jobList = new LinkedList<>();
        Boolean flag = true;
        while (flag) {
            String keyValue = dto.convertObjectToKeyValue();
            if (keyValue == null) {
                break;
            }
            String url = address + ApiConstants.GET_WORK_INFO_URL + keyValue;
            log.info("工单信息请求地址{}", url);
            String data = HttpUtil.get(url);
//            log.info("同步工单系统数据: {}", data);
            if (data == null) {
                break;
            }
            JSONObject jsonObject = JSONObject.parseObject(data);
            Integer status = jsonObject.getInteger("status");
            if (status != 200) {
                break;
            }
            JSONObject dataJson = jsonObject.getJSONObject("data");
            Integer totalNum = dataJson.getInteger("totalElements");
            Integer pageNum = dataJson.getInteger("pageNum");
            Integer pageSize = dataJson.getInteger("pageSize");
            JSONArray resultArray = dataJson.getJSONArray("result");
            if (resultArray == null) {
                break;
            }
            for (Object item : resultArray) {
                WorkHttpVO vo = JSONObject.parseObject(JSON.toJSONString(item), WorkHttpVO.class);
                //转换成数据实体
                Job job = vo.changeObj();
                job.setWorkArea(areaIdentify(vo.getLocation_desc()));
                job.setRiskLevel(riskLevelConvert(vo.getWolo6()));
                Integer unitNum = unitNumMap.get(vo.getPlusunit());
                job.setUnitNum(unitNum == null ? NumericalConstants.ONE : unitNum);
                String woeq11 = vo.getWoeq11();
                if (StringUtils.isNotBlank(woeq11) && woeq11.equals("是")) {
                    job.setAreaType(NumericalConstants.ONE);
                }
                jobList.add(job);
            }
//            log.info("转换后的工单信息{}", jobList);
            if (jobList.size() >= totalNum) {
                break;
            }
            //读取下一页数据
            dto.setPageNum(pageNum + 1);
        }
        return jobList;
    }

    /**
     * 机组号转换
     *
     * @param plusunit
     * @return java.lang.Integer
     * @author ljx
     * @time 2024/8/22 12:20
     */
//    private static Integer unitNumConvert(String plusunit) {
//        Integer result = null;
//        if (StringUtils.isNotBlank(plusunit)) {
//            if (plusunit.equals(HY1)) {
//                result = NumericalConstants.ONE;
//            } else if (plusunit.equals(HY2)) {
//                result = NumericalConstants.TWO;
//            }
//        }
//        return result;
//    }

    /**
     * 风险等级转换
     *
     * @param wolo6
     * @return java.lang.Integer
     * @author ljx
     * @time 2024/8/22 11:26
     */
    private static Integer riskLevelConvert(String wolo6) {
        Integer result = NumericalConstants.ONE;
        if (StringUtils.isNotBlank(wolo6)) {
            if (wolo6.contains("中")) {
                result = NumericalConstants.TWO;
            } else if (wolo6.contains("高")) {
                result = NumericalConstants.THREE;
            }
        }
        return result;
    }

    /**
     * 作业区域匹配
     *
     * @param locationDesc
     * @return java.lang.String
     * @author ljx
     * @time 2024/8/18 16:15
     */
    private static String areaIdentify(String locationDesc) {
        String result = "";
        if (StringUtils.isBlank(locationDesc)) {
            result = "0m层";
        } else {
            if (locationDesc.contains("0m")) {
                result = "0m层";
            } else if (locationDesc.contains("7.5")) {
                result = "7.5m层";
            } else if (locationDesc.contains("16")) {
                result = "16m层";
            } else if (locationDesc.contains("9.5")) {
                result = "-9.5m层";
            } else {
                result = locationDesc;
            }
        }
        return result;
    }

    /**
     * 修改工单信息获取
     * 之前已同步过的工单，此方法作用为返回待更新工单信息
     *
     * @param address
     * @param lists
     * @return java.util.List<com.bsj.power.common.def.entity.job.Job>
     * @author ljx
     * @time 2024/8/10 14:32
     */
    public static List<Job> updateWorkInfoHttpGet(String address, List<List<String>> lists) {
        List<Job> jobs = new LinkedList<>();
        for (List<String> woNumList : lists) {
            String param = "pageNum=1&pageSize=100&type=2&wonum=" + woNumList.stream().map(str -> "'" + str + "'").collect(Collectors.joining(","));
            String url = address + ApiConstants.GET_WORK_INFO_URL + param;
//            log.info("修改工单信息请求地址{}", url);
            String data = HttpUtil.get(url);
//            log.info("工单同步修改返回数据{}", data);
            if (StringUtils.isBlank(data)) {
                log.info("工单同步修改返回数据为空");
                continue;
            }
            JSONObject jsonObject = JSONObject.parseObject(data);
            Integer status = jsonObject.getInteger("status");
            if (status != 200) {
                log.info("工单同步修改请求失败，状态不为200");
                continue;
            }
            JSONObject dataJson = jsonObject.getJSONObject("data");
//            Integer totalNum = dataJson.getInteger("totalElements");
//            Integer pageNum = dataJson.getInteger("pageNum");
//            Integer pageSize = dataJson.getInteger("pageSize");
            JSONArray resultArray = dataJson.getJSONArray("result");
            if (CollectionUtils.isEmpty(resultArray)) {
                log.info("工单同步修改返回数据json数组为空");
                continue;
            }
            jobs.addAll(resultArray.stream().map(item -> {
                WorkHttpVO vo = JSONObject.parseObject(JSON.toJSONString(item), WorkHttpVO.class);
                //转换成数据实体
                Job job = vo.changeObj();
                job.setWorkArea(areaIdentify(vo.getLocation_desc()));
                job.setRiskLevel(riskLevelConvert(vo.getWolo6()));
                Integer unitNum = unitNumMap.get(vo.getPlusunit());
                job.setUnitNum(unitNum == null ? NumericalConstants.ONE : unitNum);
                String woeq11 = vo.getWoeq11();
                if (StringUtils.isNotBlank(woeq11) && woeq11.equals("是")) {
//                    log.info(job.getJobNum()+"为敏感区域");
                    job.setAreaType(NumericalConstants.ONE);
                }
                return job;
            }).collect(Collectors.toSet()));
//            if (jobs.size() >= totalNum) {
//                break;
//            }
//            log.info("同步工单系统数据数目: {}", resultArray.size());
        }
        return jobs;
    }

    /**
     * 质量计划数据HTTP请求
     * 可能不止100条，因为一个工单可以对应多个质量计划
     *
     * @param address
     * @param jobNum
     * @return java.util.List<com.bsj.power.common.def.entity.job.QualityPlan>
     * @author ljx
     * @time 2024/7/16 15:07
     */
    public static List<QualityPlan> qualityPlanInfoHttpGet(String address, String jobNum) {
        List<QualityPlan> qualityPlans = null;
        String str = HttpUtil.get(address + ApiConstants.GET_QUALITY_PLAN_INFO + "&wonum=" + jobNum);
        log.info("质量计划请求地址{}", address + ApiConstants.GET_QUALITY_PLAN_INFO + "&wonum=" + jobNum);
        if (StringUtils.isNotBlank(str)) {
            JSONObject data = JSONObject.parseObject(str);
            Integer status = data.getInteger("status");
            if (status != null && status.equals(JsonResultEnum.SUCCESS.getCode())) {
//                JSONObject jsonData = data.getJSONObject("data");
                JSONArray jsonArray = data.getJSONArray("data");
                if (!CollectionUtils.isEmpty(jsonArray)) {
                    List<HttpQualityPlanVO> httpQualityPlanVOS = jsonArray.toJavaList(HttpQualityPlanVO.class);
                    if (!CollectionUtils.isEmpty(httpQualityPlanVOS)) {
                        qualityPlans = httpQualityPlanVOS.stream().map(httpQualityPlanVO -> {
                            QualityPlan qualityPlan = new QualityPlan(httpQualityPlanVO);
                            String wpm1 = httpQualityPlanVO.getWpm1();
                            String requestBy = httpQualityPlanVO.getRequestby();
                            String certifyPerson = httpQualityPlanVO.getCertifyperson();
                            if (StringUtils.isNotBlank(wpm1)) {
                                qualityPlan.setQcType(wpm1ToType(wpm1));
                            }
                            qualityPlan.setSignedBy(requestBy);
                            qualityPlan.setEyewitness(StringUtils.isBlank(certifyPerson) ? null : Integer.parseInt(certifyPerson));
                            //TODO QC状态
                            qualityPlan.setQcState(null);
                            return qualityPlan;
                        }).collect(Collectors.toList());
                    }
                }
            }
        }
        return qualityPlans;
    }

    /**
     * 人员数据（负责人）HTTP请求
     *
     * @param address
     * @param directorId
     * @return java.util.List<com.bsj.power.common.def.entity.personnel.Personnel>
     * @author ljx
     * @time 2024/7/16 17:13
     */
    public static List<Personnel> personnelInfoHttpGet(String address, String directorId) {
        List<Personnel> personnelList = new LinkedList<>();
        String str = HttpUtil.get(address + ApiConstants.PAGE_GET_PERSONNEL + "&personid=" + directorId + "&pageSize=" + 100 + "&pageNum=" + 1);
        log.info("负责人员请求地址{}", address + ApiConstants.PAGE_GET_PERSONNEL + "&personid=" + directorId + "&pageSize=" + 100 + "&pageNum=" + 1);
        if (StringUtils.isNotBlank(str)) {
            JSONObject data = JSONObject.parseObject(str);
            Integer status = data.getInteger("status");
            if (status != null && status.equals(JsonResultEnum.SUCCESS.getCode())) {
                JSONObject jsonData = data.getJSONObject("data");
                JSONArray jsonArray = jsonData.getJSONArray("result");
                if (!CollectionUtils.isEmpty(jsonArray)) {
                    List<HttpPersonnelVO> httpPersonnelVOS = jsonArray.toJavaList(HttpPersonnelVO.class);
                    if (!CollectionUtils.isEmpty(httpPersonnelVOS)) {
                        for (HttpPersonnelVO httpPersonnelVO : httpPersonnelVOS) {
                            Personnel personnel = new Personnel(httpPersonnelVO);
                            String personId = httpPersonnelVO.getPersonid();
                            personnel.setDirectorId(personId);
                            String sex = httpPersonnelVO.getN_sex();
                            String nAge = httpPersonnelVO.getN_age();
                            String nPost = httpPersonnelVO.getN_post();
                            personnel.setGender(NumericalConstants.ONE);
                            if (StringUtils.isNotBlank(sex) && sex.equals("女")) {
                                personnel.setGender(NumericalConstants.TWO);
                            }
                            if (StringUtils.isNotBlank(nPost)) {
                                personnel.setType(postToType(nPost));
                            }
                            //此处年龄固定为同步时计算结果，前端显示时再根据出生日期计算
                            if (StringUtils.isNotBlank(nAge)) {
                                personnel.setAge(DateUtils.getAgeByDate(nAge));
                            }
                            personnelList.add(personnel);
                        }
                    }
                }
            }
        }
        return personnelList;
    }

    /**
     * 基站、标签HTTP请求
     *
     * @param address
     * @return java.util.List<com.bsj.power.common.def.entity.locationDevice.LocationDevice>
     * @author ljx
     * @time 2024/8/9 9:38
     */
    public static List<LocationDevice> locationDeviceInfoHttpGet(String address) {
        List<LocationDevice> locationDevices = new LinkedList<>();
        //基站设备
        String str = HttpUtil.get(address + ApiConstants.GET_ALL_ANCHOR);
        if (StringUtils.isNotBlank(str)) {
            JSONObject result = JSONObject.parseObject(str);
            if (result.getInteger("code").equals(JsonResultEnum.SUCCESS.getCode())) {
                JSONArray jsonArray = result.getJSONArray("data");
                if (!CollectionUtils.isEmpty(jsonArray)) {
                    List<HttpTagInfoVO> httpTagInfoVOS = jsonArray.toJavaList(HttpTagInfoVO.class);
                    if (!CollectionUtils.isEmpty(httpTagInfoVOS)) {
                        log.info("基站总数量{}", httpTagInfoVOS.size());
                        locationDevices.addAll(httpTagInfoVOS.stream().map(httpTagInfoVO -> {
                            return new LocationDevice(httpTagInfoVO, NumericalConstants.ONE, null);
                        }).collect(Collectors.toMap(LocationDevice::getDeviceName, a -> a, (k1, k2) -> k1)).values().stream().collect(Collectors.toList()));
                    }
                }
            }
        }
        //标签设备
        str = HttpUtil.get(address + ApiConstants.GET_ALL_TAG);
        if (StringUtils.isNotBlank(str)) {
            JSONObject result = JSONObject.parseObject(str);
            if (result.getInteger("code").equals(JsonResultEnum.SUCCESS.getCode())) {
                JSONArray jsonArray = result.getJSONArray("data");
                if (!CollectionUtils.isEmpty(jsonArray)) {
                    List<HttpTagInfoVO> httpTagInfoVOS = jsonArray.toJavaList(HttpTagInfoVO.class);
                    if (!CollectionUtils.isEmpty(httpTagInfoVOS)) {
                        log.info("标签总数量{}", httpTagInfoVOS.size());
                        locationDevices.addAll(httpTagInfoVOS.stream().map(httpTagInfoVO -> {
                            return new LocationDevice(httpTagInfoVO, NumericalConstants.TWO, NumericalConstants.THREE);
                        }).collect(Collectors.toMap(LocationDevice::getDeviceName, a -> a, (k1, k2) -> k1)).values().stream().collect(Collectors.toList()));
                    }

                }
            }
        }
        return locationDevices;
    }

    /**
     * 数据透传接口
     *
     * @param st 透传数据类型 A：声光报警下发 B：其他
     * @param address 请求地址
     * @param id      下发设备号
     * @param hexStr  下发数据体
     * @return
     */
    public static boolean transmitDataHttpPut(String st, String address, String id, String hexStr) {
        String url = address + ApiConstants.TRANSMIT_DATA_URL.replaceAll("\\{id\\}", id);
        //请求包含 hex|utf8|base64 三种方式,当前使用hex
        String paramBody = JSON.toJSONString(Map.of("data", hexStr, "codec", "hex"));
        if ("A".equalsIgnoreCase(st)) {
            //声光报警每0.5秒发10次
            for (int i = 0; i < 10; i++) {
                HttpRequest request = HttpRequest.put(url).body(paramBody);
                HttpResponse response = request.execute();
                String data = response.body();
                log.info("UWB数据透传类型： {}, 设备ID： {}, PUT请求url: {}, 请求结果: {}", st, id, url, data);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    log.error("声光报警发送错误: {}", ExceptionUtil.getStackStr(e));
                    continue;
                }
                if (data == null) {
                    continue;
                }
                JSONObject jsonObject = JSON.parseObject(data);
                Integer code = jsonObject.getInteger("code");
                if (code != 200) {
                    continue;
                }
            }
        } else {
            HttpRequest request = HttpRequest.put(url).body(paramBody);
            HttpResponse response = request.execute();
            String data = response.body();
            log.info("UWB数据透传类型： {}, 设备ID： {}, PUT请求url: {}, 请求结果: {}", st, id, url, data);
            if (data == null) {
                return false;
            }
            JSONObject jsonObject = JSON.parseObject(data);
            Integer code = jsonObject.getInteger("code");
            if (code != 200) {
                return false;
            }
        }
        return true;
    }

    /**
     * 岗位转类型
     *
     * @param nPost
     * @return void
     * @author ljx
     * @time 2024/7/10 14:01
     */
    private static Integer postToType(String nPost) {
        Integer type;
        switch (nPost) {
            case "管理人员":
                type = NumericalConstants.ONE;
                break;
            case "安全巡视人员":
                type = NumericalConstants.TWO;
                break;
            case "运行人员":
                type = NumericalConstants.THREE;
                break;
            case "维修人员":
                type = NumericalConstants.FOUR;
                break;
            case "其他人员":
            default:
                type = NumericalConstants.FIVE;
                break;
        }
        return type;
    }

    /**
     * QC类型转换
     *
     * @param wpm1
     * @return java.lang.Integer
     * @author ljx
     * @time 2024/7/11 11:44
     */
    private static Integer wpm1ToType(String wpm1) {
        Integer type;
        switch (wpm1) {
            case "A":
                type = NumericalConstants.ONE;
                break;
            case "B":
                type = NumericalConstants.TWO;
                break;
            case "C":
                type = NumericalConstants.THREE;
                break;
            default:
                type = NumericalConstants.ZERO;
                log.info("错误的QC类型{}", wpm1);
                break;
        }
        return type;
    }

    public static void main(String[] args) {
//        WorkHttpDTO dto = WorkHttpDTO.builder()
//                .wonum("1122")
//                .pageNum(1)
//                .pageSize(10)
//                .targcompdate("2024-07-10")
//                .build();
//        System.out.println(dto.convertObjectToKeyValue());
    }
}
